package edu.manju.mimi.lord.controller;

import com.github.cm.heclouds.onenet.studio.api.entity.common.CreateDeviceResponse;
import com.github.cm.heclouds.onenet.studio.api.entity.common.DeleteDeviceResponse;
import com.github.cm.heclouds.onenet.studio.api.exception.IotClientException;
import com.github.cm.heclouds.onenet.studio.api.exception.IotServerException;
import edu.manju.mimi.core.R;
import edu.manju.mimi.core.security.CurrentUserId;
import edu.manju.mimi.core.security.NeedAuth;
import edu.manju.mimi.db.service.IDeviceService;
import edu.manju.mimi.db.entity.Device;
import edu.manju.mimi.lord.service.IotDeviceService;
import edu.manju.mimi.lord.vo.DeviceCreateInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <h4>mimi-lord-server</h4>
 * <p>设备控制器</p>
 *
 * @author : Lebei(lebei163@163.com)
 * @date : 2023-03-03 16:07
 **/
@RestController
@RequestMapping("/device")
public class DeviceController {
    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IotDeviceService iotDeviceService;

    @GetMapping("/search/{section}")
    @NeedAuth
    public R<List<Device>> getDevicesOfLord(@CurrentUserId Integer userId,
                                            @PathVariable String section) {
        List<Device> devices = section.equals("全部")
                ? deviceService.getDevicesByLordId(userId)
                : deviceService.getDevicesByLordIdAndSection(userId, section);
        return R.ok(devices);
    }

    @GetMapping("/list/{deviceId}")
    @NeedAuth
    public R<Device> getDeviceOfLord(@CurrentUserId Integer userId,
                                     @PathVariable Integer deviceId) {
        Device device = deviceService.getDeviceByLordIdAndDeviceId(userId, deviceId);
        return R.ok(device);
    }

    @PostMapping("/create")
    @NeedAuth
    public R<CreateDeviceResponse> createDevice(@CurrentUserId Integer userId,
                                                @RequestBody DeviceCreateInfo deviceInfo) {
        Device device = deviceService.selectByLordIdAndName(userId, deviceInfo.getName());
        if (device != null) {
            return R.fail("Device already exists: " + deviceInfo.getName());
        }

        device = new Device();
        device.setName(deviceInfo.getName());
        device.setAddress(deviceInfo.getAddress());
        device.setSection(deviceInfo.getSection());
        device.setLongitude(deviceInfo.getLongitude());
        device.setLatitude(deviceInfo.getLatitude());
        device.setVendor(deviceInfo.getVendor());
        device.setPortNum(deviceInfo.getPortNum());
        device.setLordId(userId);

        boolean saved = deviceService.save(device);
        if (!saved) {
            return R.fail("Cannot save device: " + deviceInfo.getName());
        }

        CreateDeviceResponse response = null;
        try {
            response = iotDeviceService.createDevice(
                    userId,
                    device.getId(),
                    deviceInfo.getName());
        } catch (IotServerException | IotClientException e) {
            return R.fail(e.getMessage());
        }

        device.setIotCreated((byte) 1);
        boolean updated = deviceService.updateById(device);
        if (updated) {
            return R.ok(response);
        } else {
            return R.fail("Cannot update device: " + deviceInfo.getName());
        }
    }

    @DeleteMapping("/remove/{deviceId}")
    @NeedAuth
    public R<DeleteDeviceResponse> deleteDevice(@CurrentUserId Integer userId,
                                                @PathVariable Integer deviceId) {
        DeleteDeviceResponse response = null;
        try {
            response = iotDeviceService.deleteDevice(userId, deviceId);
        } catch (IotServerException | IotClientException e) {
            return R.fail(e.getMessage());
        }

        boolean saved = deviceService.removeByByLordIdAndDeviceId(userId, deviceId);
        if (!saved) {
            return R.fail("Cannot remove device: " + deviceId);
        }

        return R.ok(response);
    }
}
